#pragma once
#include <brpc/channel.h>
#include <brpc/naming_service.h>
#include <brpc/server.h>
#include <memory>
#include <httplib.h>
#include "blog.pb.h"
#include "brpc.h"
#include "etcd_path.h"



class BlogModule{
private:
    std::shared_ptr<brpc::Channel> _channel;
    std::shared_ptr<blog::BlogService_Stub> _blogservice_stub;
public:
    using ptr = std::shared_ptr<BlogModule>;
    BlogModule(const std::string& etcd_path){
        _channel = lyt::build_etcd(etcd_path, lyt::blog_path);
        _blogservice_stub = make_shared<blog::BlogService_Stub>(_channel.get());
    }

    void blogList(const httplib::Request &req, httplib::Response &res){
        /*
            1. 创建proto请求对象与响应对象
            2. 解析二进制数据
            3. 交给BlogList服务
        */
        blog::BlogListRequest bloglistrequest;
        blog::BlogListResponse bloglistresponse;
        if (!bloglistrequest.ParseFromArray(req.body.data(), req.body.size())) {
            res.status = 400;
            res.set_content("Invalid data", "text/plain");
            return;
        }
        brpc::Controller cntl;
        _blogservice_stub->BlogList(&cntl, &bloglistrequest, &bloglistresponse, nullptr);
        if (cntl.Failed()) {
            res.status = 500;
            res.set_content("RPC Failed: " + cntl.ErrorText(), "text/plain");
            return;
        }
        string res_bin;
        bloglistresponse.SerializeToString(&res_bin);
        res.status = 200;
        res.set_content(res_bin, "application/octet-stream");
    }
    void blogDetail(const httplib::Request &req, httplib::Response &res){
        /*
            1. 创建proto请求对象与响应对象
            2. 解析二进制数据
            3. 交给BLOGDetail服务
        */
        blog::BlogDetailRequest blogdetailrequest;
        blog::BlogDetailResponse blogdetailresponse;
        if (!blogdetailrequest.ParseFromArray(req.body.data(), req.body.size())) {
            res.status = 400;
            res.set_content("Invalid data", "text/plain");
            return;
        }
        brpc::Controller cntl;
        _blogservice_stub->BLOGDetail(&cntl, &blogdetailrequest, &blogdetailresponse, nullptr);
        if (cntl.Failed()) {
            res.status = 500;
            res.set_content("RPC Failed: " + cntl.ErrorText(), "text/plain");
            return;
        }
        string res_bin;
        blogdetailresponse.SerializeToString(&res_bin);
        res.status = 200;
        res.set_content(res_bin, "application/octet-stream");
    }
    void blogLike(const httplib::Request &req, httplib::Response &res){
        /*
            1. 创建proto请求对象与响应对象
            2. 解析二进制数据
            3. 交给Like服务
        */
        blog::LikeRequest likerequest;
        blog::LikeResponse likeresponse;
        if (!likerequest.ParseFromArray(req.body.data(), req.body.size())) {
            res.status = 400;
            res.set_content("Invalid data", "text/plain");
            return;
        }
        brpc::Controller cntl;
        _blogservice_stub->Like(&cntl, &likerequest, &likeresponse, nullptr);
        if (cntl.Failed()) {
            res.status = 500;
            res.set_content("RPC Failed: " + cntl.ErrorText(), "text/plain");
            return;
        }
        string res_bin;
        likeresponse.SerializeToString(&res_bin);
        res.status = 200;
        res.set_content(res_bin, "application/octet-stream");
    }
    void blogComment(const httplib::Request &req, httplib::Response &res){
        /*
            1. 创建proto请求对象与响应对象
            2. 解析二进制数据
            3. 交给Comment服务
        */
        blog::CommentRequest commnetrequest;
        blog::CommentResponse commentresponse;
        if (!commnetrequest.ParseFromArray(req.body.data(), req.body.size())) {
            res.status = 400;
            res.set_content("Invalid data", "text/plain");
            return;
        }
        brpc::Controller cntl;
        _blogservice_stub->Comment(&cntl, &commnetrequest, &commentresponse, nullptr);
        if (cntl.Failed()) {
            res.status = 500;
            res.set_content("RPC Failed: " + cntl.ErrorText(), "text/plain");
            return;
        }
        string res_bin;
        commentresponse.SerializeToString(&res_bin);
        res.status = 200;
        res.set_content(res_bin, "application/octet-stream");
    }
    void blogGetcomment(const httplib::Request &req, httplib::Response &res){
        /*
            1. 创建proto请求对象与响应对象
            2. 解析二进制数据
            3. 交给Getcomment服务
        */
        blog::BlogCommentRequest blogcommnetrequest;
        blog::BlogCommentResponse blogcommentresponse;
        if (!blogcommnetrequest.ParseFromArray(req.body.data(), req.body.size())) {
            res.status = 400;
            res.set_content("Invalid data", "text/plain");
            return;
        }
        brpc::Controller cntl;
        _blogservice_stub->BlogComment(&cntl, &blogcommnetrequest, &blogcommentresponse, nullptr);
        if (cntl.Failed()) {
            res.status = 500;
            res.set_content("RPC Failed: " + cntl.ErrorText(), "text/plain");
            return;
        }
        string res_bin;
        blogcommentresponse.SerializeToString(&res_bin);
        res.status = 200;
        res.set_content(res_bin, "application/octet-stream");
    }
    void blogDelete(const httplib::Request &req, httplib::Response &res){
        /*
            1. 创建proto请求对象与响应对象
            2. 解析二进制数据
            3. 交给删除博客服务
        */
        blog::DeleteBlogRequest deleteblogrequest;
        blog::DeleteBlogResponse deleteblogresponse;
        if (!deleteblogrequest.ParseFromArray(req.body.data(), req.body.size())) {
            res.status = 400;
            res.set_content("Invalid data", "text/plain");
            return;
        }
        brpc::Controller cntl;
        _blogservice_stub->DeleteBlog(&cntl, &deleteblogrequest, &deleteblogresponse, nullptr);
        if (cntl.Failed()) {
            res.status = 500;
            res.set_content("RPC Failed: " + cntl.ErrorText(), "text/plain");
            return;
        }
        string res_bin;
        deleteblogresponse.SerializeToString(&res_bin);
        res.status = 200;
        res.set_content(res_bin, "application/octet-stream");
    }
    void blogCreate(const httplib::Request &req, httplib::Response &res){
        /*
            1. 创建proto请求对象与响应对象
            2. 解析二进制数据
            3. 交给创建博客服务
        */
        blog::CreateBlogRequest createblogrequest;
        blog::CreateBlogResponse createblogresponse;
        if (!createblogrequest.ParseFromArray(req.body.data(), req.body.size())) {
            res.status = 400;
            res.set_content("Invalid data", "text/plain");
            return;
        }
        brpc::Controller cntl;
        _blogservice_stub->CreateBlog(&cntl, &createblogrequest, &createblogresponse, nullptr);
        if (cntl.Failed()) {
            res.status = 500;
            res.set_content("RPC Failed: " + cntl.ErrorText(), "text/plain");
            return;
        }
        string res_bin;
        createblogresponse.SerializeToString(&res_bin);
        res.status = 200;
        res.set_content(res_bin, "application/octet-stream");
    }
    void blogEdit(const httplib::Request &req, httplib::Response &res){
        /*
            1. 创建proto请求对象与响应对象
            2. 解析二进制数据
            3. 交给编辑博客
        */
        blog::EditBlogRequest editblogrequest;
        blog::EditBlogResponse editblogresponse;
        if (!editblogrequest.ParseFromArray(req.body.data(), req.body.size())) {
            res.status = 400;
            res.set_content("Invalid data", "text/plain");
            return;
        }
        brpc::Controller cntl;
        _blogservice_stub->EditBlog(&cntl, &editblogrequest, &editblogresponse, nullptr);
        if (cntl.Failed()) {
            res.status = 500;
            res.set_content("RPC Failed: " + cntl.ErrorText(), "text/plain");
            return;
        }
        string res_bin;
        editblogresponse.SerializeToString(&res_bin);
        res.status = 200;
        res.set_content(res_bin, "application/octet-stream");
    }
    void blogLikelist(const httplib::Request &req, httplib::Response &res){
        /*
            1. 创建proto请求对象与响应对象
            2. 解析二进制数据
            3. 交给获取喜欢列表服务
        */
        blog::LikedBlogListRequest likedbloglistrequest;
        blog::LikedBlogListResponse likedbloglistresponse;
        if (!likedbloglistrequest.ParseFromArray(req.body.data(), req.body.size())) {
            res.status = 400;
            res.set_content("Invalid data", "text/plain");
            return;
        }
        brpc::Controller cntl;
        _blogservice_stub->LikedBlogList(&cntl, &likedbloglistrequest, &likedbloglistresponse, nullptr);
        if (cntl.Failed()) {
            res.status = 500;
            res.set_content("RPC Failed: " + cntl.ErrorText(), "text/plain");
            return;
        }
        string res_bin;
        likedbloglistresponse.SerializeToString(&res_bin);
        res.status = 200;
        res.set_content(res_bin, "application/octet-stream");
    }
    void blogLikedelete(const httplib::Request &req, httplib::Response &res){
        /*
            1. 创建proto请求对象与响应对象
            2. 解析二进制数据
            3. 交给删除喜欢博客服务
        */
        blog::DeleteLikeBlogRequest deletelikeblogrequest;
        blog::DeleteLikeBlogResponse deletelikeblogresponse;
        if (!deletelikeblogrequest.ParseFromArray(req.body.data(), req.body.size())) {
            res.status = 400;
            res.set_content("Invalid data", "text/plain");
            return;
        }
        brpc::Controller cntl;
        _blogservice_stub->DeleteLikeBlog(&cntl, &deletelikeblogrequest, &deletelikeblogresponse, nullptr);
        if (cntl.Failed()) {
            res.status = 500;
            res.set_content("RPC Failed: " + cntl.ErrorText(), "text/plain");
            return;
        }
        string res_bin;
        deletelikeblogresponse.SerializeToString(&res_bin);
        res.status = 200;
        res.set_content(res_bin, "application/octet-stream");
    }
    void blogUser(const httplib::Request &req, httplib::Response &res){
        /*
            1. 创建proto请求对象与响应对象
            2. 解析二进制数据
            3. 交给删除喜欢博客服务
        */
        blog::UserBlogListRequest userbloglistrequest;
        blog::BlogListResponse bloglistresponse;
        if (!userbloglistrequest.ParseFromArray(req.body.data(), req.body.size())) {
            res.status = 400;
            res.set_content("Invalid data", "text/plain");
            return;
        }
        brpc::Controller cntl;
        _blogservice_stub->UserBlogList(&cntl, &userbloglistrequest, &bloglistresponse, nullptr);
        if (cntl.Failed()) {
            res.status = 500;
            res.set_content("RPC Failed: " + cntl.ErrorText(), "text/plain");
            return;
        }
        string res_bin;
        bloglistresponse.SerializeToString(&res_bin);
        res.status = 200;
        res.set_content(res_bin, "application/octet-stream");
    }

};